﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI;

namespace PTA.Web
{
    /// <summary>
    /// WEB页面的基类
    /// </summary>
    public class PageBase : System.Web.UI.Page
    {
        /// <summary>
        /// 日志
        /// </summary>
        protected LogAdapter logger = LogAdapter.GetLogger("WebPage");

        #region 回调处理
        /// <summary>
        /// 在页面注册回调方法并返回调用这个回调方法的字符串
        /// <para>
        ///     调用这个方法会在页面中注册一个__doPostBack(eventTarget, eventArgument)方法,这个方法会返回一个使用指定控件和参数来调用__doPostBack方法的字符串
        /// </para>
        /// </summary>
        protected string PostBack(Control ctl, string args)
        {
            if (ctl != null)
            {
                return ClientScript.GetPostBackEventReference(ctl, args);
            }
            throw new Exception("触发回传事件的控件不能为空");
        }

        /// <summary>
        /// 产生回调的事件的源控件
        /// </summary>
        protected string EventTarget
        {
            get
            {
                return Request.Form["__EVENTTARGET"];
            }
        }

        /// <summary>
        /// 产生回调事件时的参数
        /// </summary>
        protected string EventArgument
        {
            get
            {
                return Request.Form["__EVENTARGUMENT"];
            }
        }
        #endregion

        #region 添加样式和脚本
        /// <summary>
        /// 要添加的js文件的路径
        /// </summary>
        /// <param name="path">要添加的js文件的路径</param>
        public void AddJsFile(string path)
        {
            WebContext.AddJsFile(this, path);
        }

        /// <summary>
        /// 要添加的js文件的路径
        /// </summary>
        /// <param name="path">要添加的js文件的路径</param>
        /// <param name="index">要添加的js文件在网页中的位置</param>
        public void AddJsFile(string path, int index)
        {
            WebContext.AddJsFile(this, path, index);
        }

        /// <summary>
        /// 向客户端添加CSS文件
        /// </summary>
        /// <param name="path">要添加的CSS文件的路径</param>
        public void AddCssFile(string path)
        {
            WebContext.AddCssFile(this, path);
        }

        /// <summary>
        /// 向客户端添加CSS文件
        /// </summary>
        /// <param name="path">要添加的CSS文件的路径</param>
        /// <param name="index">要添加的CSS文件在网页中的位置</param>
        public void AddCssFile(string path, int index)
        {
            WebContext.AddCssFile(this, path, index);
        }
        #endregion

        #region 检查是否是用户提交页面,还是刷新页面.
        private static readonly string SubmitTicket = "__CHECKVALIDSUBMITTICKET";
        /// <summary>
        /// 在页面初始化之前要检查是否提交表单,并写入时间戳
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_PreInit(object sender, EventArgs e)
        {
            HttpContext.Current.Items[SubmitTicket] = !IsPostBack;
            if (IsPostBack && (Request.Form[SubmitTicket] != null) && (Session[SubmitTicket] == null || Request.Form[SubmitTicket] != Session[SubmitTicket].ToString()))
            {
                Session[SubmitTicket] = Request.Form[SubmitTicket];
                HttpContext.Current.Items[SubmitTicket] = true;
            }
            this.ClientScript.RegisterHiddenField(SubmitTicket, DateTime.Now.Ticks.ToString()); //写入最后请求的时间戳
        }

        /// <summary>
        /// 返回一个值,如果用户是提交数据,则为true,如果用户是刷新网页或首次打开,则为false.
        /// <para>
        /// 要使用此方法,必须要设置允许使用Session.
        /// </para>
        /// </summary>
        public bool IsValidPostBack
        {
            get
            {
                return PTA.Convert.ToBoolean(HttpContext.Current.Items[SubmitTicket] ?? false);
            }
        }
        #endregion

        /// <summary>
        /// Alert一个错误
        /// </summary>
        /// <param name="msg">错误信息</param>
        protected void Alert(string msg)
        {
            Alert(msg, false);
        }

        /// <summary>
        /// Alert一个错误
        /// </summary>
        /// <param name="msg">错误信息</param>
        /// <param name="end">是否在提示错误后停止输出</param>
        protected void Alert(string msg, bool end)
        {
            if (end)
            {
                Response.Write(string.Format("<script type='text/javascript'>alert('{0}');</script>", msg));
                Response.End();
            }
            else
            {
                ClientScript.RegisterStartupScript(this.GetType(), DateTime.Now.Ticks.ToString(), string.Format("alert('{0}');", msg), true);
            }
        }

        /// <summary>
        /// Alert一个错误,并把网页转到指定的地址
        /// </summary>
        /// <param name="msg">错误信息</param>
        /// <param name="target">跳转地址</param>
        protected void Alert(string msg, string target)
        {
            Alert(msg, target, false);
        }

        /// <summary>
        /// Alert一个错误
        /// </summary>
        /// <param name="msg">错误信息</param>
        /// <param name="target">跳转地址</param>
        /// <param name="top">是否在最上层窗口跳转</param>
        protected void Alert(string msg, string target, bool top)
        {
            if (top)
            {
                Response.Write(string.Format("<script type='text/javascript'>alert('{0}');window.top.location.href='{0}';</script>", msg, target));
                Response.End();
            }
            else
            {
                Response.Write(string.Format("<script type='text/javascript'>alert('{0}');window.location.href='{0}';</script>", msg, target));
                Response.End();
            }
        }

        #region 处理异常
        /// <summary>
        /// 处理异常
        /// </summary>
        /// <param name="sender">源</param>
        /// <param name="e">事件</param>
        protected void Page_Error(object sender, EventArgs e)
        {
            Exception ex = Server.GetLastError();
            CatchError(ex);
        }

        /// <summary>
        /// 记录异常信息
        /// </summary>
        /// <param name="ex"></param>
        protected virtual void CatchError(Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("异常位置:" + ex.TargetSite.ReflectedType.FullName + "." + ex.TargetSite.Name);
            sb.AppendLine("原始路径:" + Request.Url);
            sb.AppendLine("物理路径:" + Request.PhysicalPath);
            sb.AppendLine("错误信息:" + ex.Message);
            sb.AppendLine("内部错误:" + ex.InnerException);
            sb.AppendLine("堆栈信息:");
            sb.Append(ex.StackTrace);
            logger.Error(sb, false);
            throw ex;
        }
        #endregion

        [System.ComponentModel.Browsable(true)]
        public string FormClass
        {
            get { return this.Form.Attributes["class"]; }
            set { this.Form.Attributes["class"] = value; }
        }

        public PTA.ContextMessage Ctx
        {
            get
            {
                return PTA.ContextMessage.Current;
            }
        }

    }
}
